package com.wyu.notaryserver.util;

import com.fasterxml.jackson.databind.node.ArrayNode;
import okhttp3.*;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.wyu.notaryserver.domain.OcrImageDTO;
import org.springframework.stereotype.Component;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Base64;
import java.util.List;
import java.util.Objects;
import java.util.zip.Deflater;

@Component
public class OCR {
    private static final ObjectMapper objectMapper = new ObjectMapper();
    private static final OkHttpClient client = new OkHttpClient();
    private static final MediaType JSON = MediaType.Companion.get("application/json; charset=utf-8");

    // 通用的 OCR 请求处理方法
    private static OcrImageDTO processOCRRequest(List<String> base64ImageDataList,String tit) throws IOException {

            //OCR地址更改
            String API_URL;
            // 根据 tit 的值选择不同的接口地址
            if (Objects.equals(tit, "1")) {
                API_URL = "https://ocr.wygzc.cn/ocr"; // 用于文字识别
            } else {
                API_URL = "https://ocr.wygzc.cn/captcha_ocr";  //用于验证码识别
            }

        // 过滤掉 null 值
        List<String> validBase64ImageDataList = new ArrayList<>();
        for (String base64ImageData : base64ImageDataList) {
            if (base64ImageData != null) {
                validBase64ImageDataList.add(base64ImageData);
            }
        }

        ObjectNode params = objectMapper.createObjectNode();
        ArrayNode imagesNode = objectMapper.createArrayNode();
        for (String base64ImageData : validBase64ImageDataList) {
            imagesNode.add(base64ImageData);
        }
        params.set("images", imagesNode);

//        // 压缩Base64编码数据
//        ObjectNode Params;
//        try {
//            Params = compressBase64InParams(params);
//        } catch (Exception e) {
//            throw new RuntimeException(e);
//        }

        RequestBody body = RequestBody.Companion.create(objectMapper.writeValueAsString(params), JSON);
        Request request = new Request.Builder()
                .url(API_URL)
                .post(body)
                .addHeader("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36")
                .build();

//        String jsonBody = objectMapper.writeValueAsString(params);
//        System.out.println("Request body: " + jsonBody);

        try (Response response = client.newCall(request).execute()) {
            if (response.isSuccessful()) {
                JsonNode resultNode = null;
                if (response.body() != null) {
                    resultNode = objectMapper.readTree(response.body().string());
                }
                OcrImageDTO ocrImageDTO = new OcrImageDTO();
                // 整合提取信息的逻辑（目前使用是只传两张）
                for (int i = 0; i < 5; i++) {
                    String ocrResultKey = "ocr_results_" + i;
                    JsonNode ocrResultNode = null;
                    if (resultNode != null) {
                        ocrResultNode = resultNode.get(ocrResultKey);
                    }
                    if (ocrResultNode != null && ocrResultNode.isObject()) {
                        JsonNode textNode = ocrResultNode.get("text");
                        if (textNode != null && textNode.isArray()) {
                            String[] ocrResultArray = new String[textNode.size()];
                            for (int j = 0; j < textNode.size(); j++) {
                                ocrResultArray[j] = textNode.get(j).asText();
                            }
                            if (i == 0) {
                                ocrImageDTO.setIdCardResult(ocrResultArray);
                            } else {
                                ocrImageDTO.setPassportResult(ocrResultArray);
                            }
                        }
                    }
                }
                return ocrImageDTO;
            } else {
                throw new IOException("Request failed with code: " + response.code());
            }
        }
    }

    // 验证码 OCR，目前算法可以简单的识别出验证码
    public static String getYZM(String imagePath) throws IOException {
        Path path = Paths.get(imagePath);
        if (!Files.exists(path) ||!Files.isReadable(path)) {
            throw new IOException("文件不存在或没有读取权限: " + imagePath);
        }
        byte[] fileContent = Files.readAllBytes(path);
        String imageData = Base64.getEncoder().encodeToString(fileContent);
        int retryCount = 3;
        while (retryCount > 0) {
            OcrImageDTO ocrImageDTO = processOCRRequest(List.of(imageData), "2");
            String[] YZM = ocrImageDTO.getIdCardResult();
            if (YZM != null && YZM.length > 0) {
                return YZM[0];
            }
            retryCount--;
            System.out.println("验证码识别失败，重试次数: " + retryCount);
        }
        return "";
    }

    // 前端返回数据后 OCR 处理，返回文本和更新图片的 base64 编码
    public static OcrImageDTO getImageText(List<String> base64ImageDataList) throws IOException {
        return processOCRRequest(base64ImageDataList,"1");
    }

    /**
     * 压缩Base64编码数据并更新params对象
     * @param params 包含Base64编码数据的ObjectNode
     * @return 包含压缩后Base64编码数据的ObjectNode
     * @throws Exception 压缩或JSON处理过程中的异常
     */
    public static ObjectNode compressBase64InParams(ObjectNode params) throws Exception {
        JsonNode imagesNode = params.get("images");
        if (imagesNode == null ||!imagesNode.isArray()) {
            throw new IllegalArgumentException("params中不存在或images节点不是数组");
        }
        ArrayNode newImagesNode = objectMapper.createArrayNode();
        for (JsonNode base64ImageDataNode : imagesNode) {
            String base64ImageData = base64ImageDataNode.asText();
            byte[] decodedBytes = Base64.getDecoder().decode(base64ImageData);
            byte[] compressedBytes = compressBytes(decodedBytes);
            String compressedBase64 = Base64.getEncoder().encodeToString(compressedBytes);
            newImagesNode.add(compressedBase64);
        }
        params.set("images", newImagesNode);
        return params;
    }

    /**
     * 压缩字节数组
     * @param data 待压缩的字节数组
     * @return 压缩后的字节数组
     */
    private static byte[] compressBytes(byte[] data) {
        Deflater deflater = new Deflater();
        deflater.setInput(data);
        deflater.finish();

        ByteArrayOutputStream outputStream = new ByteArrayOutputStream(data.length);
        byte[] buffer = new byte[1024];
        while (!deflater.finished()) {
            int count = deflater.deflate(buffer);
            outputStream.write(buffer, 0, count);
        }
        deflater.end();

        return outputStream.toByteArray();
    }


}